﻿#region License
// Author: David Kirkland <davidrkirkland@gmail.com>
// Copyright 2007-2008 Illogikal Software 
//
// Licensed under the Apache License, Version 2.0 (the "License"); 
// you may not use this file except in compliance with the License. 
// You may obtain a copy of the License 
// 
//     http://www.apache.org/licenses/LICENSE-2.0 
//
// Unless required by applicable law or agreed to in writing, software 
// distributed under the License is distributed on an "AS IS" BASIS, 
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
// See the License for the specific language governing permissions and 
// limitations under the License.
#endregion

#region Using Directives
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
#endregion

namespace NetSpider.Policies
{
    public class RobotPolicy
    {
        private readonly string _domainName;
        private readonly DateTime _retrieved;
        private readonly Dictionary<string, List<string>> _disallowedUrls = new Dictionary<string, List<string>>();

        private const string DEFAULT_USER_AGENT = "*";

        public RobotPolicy(string domainName, DateTime retrieved)
        {
            _domainName = domainName;
            _retrieved = retrieved;
            _disallowedUrls.Add(DEFAULT_USER_AGENT, new List<string>());
        }

        public string DomainName
        {
            get { return _domainName; }
        }

        public DateTime Retrieved
        {
            get { return _retrieved; }
        }

        public PolicyDecision MakeDecision(string userAgent, string uri)
        {
            Uri uriToCheck = new Uri(uri);

            List<string> disallows = GetDefaultDisallows();

            foreach (string disallowed in disallows)
            {
                if (UriIsDisallowed(uriToCheck, disallowed))
                {
                    return PolicyDecision.VisitProhibited;
                }
            }

            disallows = GetDisallowsFor(userAgent);

            foreach (string disallowed in disallows)
            {
                if (UriIsDisallowed(uriToCheck, disallowed))
                {
                    return PolicyDecision.VisitProhibited;
                }
            }
            
            return PolicyDecision.VisitAllowed;
        }

        private bool UriIsDisallowed(Uri uriToCheck, string disallowed)
        {
            return disallowed.Contains(uriToCheck.GetComponents(UriComponents.Path, UriFormat.Unescaped));
        }

        private List<string> GetDefaultDisallows()
        {
            return GetDisallowsFor(DEFAULT_USER_AGENT);
        }

        private List<string> GetDisallowsFor(string userAgent)
        {
            return _disallowedUrls[userAgent];
        }

        public void AddDisallow(string userAgent, string disallowedUrl)
        {
            if (!_disallowedUrls.ContainsKey(userAgent))
            {
                _disallowedUrls.Add(userAgent, new List<string>());
            }

            _disallowedUrls[userAgent].Add(disallowedUrl);
        }
    }
}
